#ifndef _VECTOR_H_
#define _VECTOR_H_

#include "Maths.h"
#include "Define.h"
#include "Matrix.h"

namespace Math{
/**
 * classe de Vecteur standard à 3 dimentions en float
 *
 * Par choix de design, les attributs x,y, et z sont publics parce qu'il
 * seront toujours accessibles sans contraintes
 * (il n'y a pas de vérification à faire).
 * De plus, c'est vraiment plus simple et rapide d'un côté de performances et d'écriture
 **/
class MATH_API Vector{
 public:
    /**
     * Constructeur nul.
     * x=y=z=0
     */
    Vector();
    /**
     * Constructeur standard
     * @param X parametre x
     * @param Y parametre y
     * @param Z parametre z
     */
    Vector(float X,float Y,float Z);

    float x; ///< paramètre x
    float y; ///< paramètre y
    float z; ///< paramètre z
	float w; ///< paramètre w

    /**
     * Produit scalaire de vecteurs
     *
     * retourne \f$ r = \vec{a}.\vec{b} \f$
     * @param b vecteur de droite
     * @return le produit scalaire
     **/
    INLINED float dot(const Vector &b);

    /**
     * Produit vectoriel de vecteurs
     * @param b vecteur de droite
     * @return le produit vectoriel
     */
    INLINED Vector cross(const Vector &b);

    /**
     * Normalise le vecteur in-place
     */
    INLINED void normalize();

    /**
     * Retourne le vecteur normalisé
     * @return Le vecteur v normalisé
     */
    INLINED Vector normal();

    /**
     * Retourne la norme du vecteur
     * @return |v|, la norme de v
     */
    float norm();

	/**
	* Retourne un vecteur inverse à celui-ci
    * @return inverse de v
	*/
	Vector inverse();

    /**
     * Multiplication par un scalaire
     *
     * @param n scalaire
     * @return v*n
     */
    INLINED Vector operator*(const float n);

	/**
	* Division par un scalaire
	* @param n scalaire
	* @return v/n
	*/
	INLINED Vector operator/(const float n);

	/**
	* Multiplication par la droite par une matrice
	* @param mat Matrice
	* @returns v*mat
	*/
	INLINED Vector operator*(const Matrix &mat);

    /**
     * Addition à un vecteur
     *
     * @param o vecteur a additionner
     * @returns (x1+x2,y1+y2,z1+z2)
     */
    INLINED Vector operator+(const Vector &o);

    /**
     * Soustraction à un vecteur
     *
     * @param o vecteur a soustraire
     * @returns (x1-x2,y1-y2,z1-z2)
     */
    INLINED Vector operator-(const Vector &o);

    /**
     * Addition inplace
     *
     * @param o vecteur a additionner 
     */
    INLINED void operator+=(const Vector &o);

    /**
     * Soustraction inplace
     *
     * @param o vecteur a soustraire
     */
    INLINED void operator-=(const Vector &o);

	 /**
	 * Multiplication inplace
	 * @param n facteur
	 */
	 INLINED void operator*=(const float n);

	 /**
	 * Multiplication inplace par une matrice
	 * @param mat Matrice
	 */
	 INLINED void operator*=(const Matrix &mat);

     /**
      * Divison inplace
      * @param n scalaire
      */
     INLINED void operator/=(const float n);
     
	 /**
      * Comparaison à un vecteur
      *
      * @param o vecteur à comparer
      * @return v==o
      */
     INLINED bool operator==(const Vector &o);
     
     /**
      * Comparaison à un vecteur
      * @param o vecteur à comparer
      * @return v!=o
      */
     INLINED bool operator!=(const Vector &o);
};
 
} // namespace Math


#endif //_VECTOR_H_
